home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / dev / cross / GBDK-2.0.lha / GBDK / lib / crt0.s < prev    next >
Text File  |  1998-10-30  |  8KB  |  540 lines

  1.     .include    "global.s"
  2.  
  3.     ;; ****************************************
  4.     ;; Beginning of module
  5.     .title    "GB Runtime"
  6.     .module    Runtime
  7.     .area    _HEADER (ABS)
  8.  
  9.     ;; Standard header for the GB
  10.     .org    0x00
  11.     RET            ; Empty function (default for interrupts)
  12.  
  13.     .org    0x10
  14.     .byte    0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01
  15.     .byte    0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
  16.  
  17.     ;; Interrupt vectors
  18.     .org    0x40        ; VBL
  19. .int_VBL:
  20.     PUSH    HL
  21.     LD    HL,#.int_0x40
  22.     JP    .int
  23.  
  24.     .org    0x48        ; LCD
  25. .int_LCD:
  26.     PUSH    HL
  27.     LD    HL,#.int_0x48
  28.     JP    .int
  29.  
  30.     .org    0x50        ; TIM
  31. .int_TIM:
  32.     PUSH    HL
  33.     LD    HL,#.int_0x50
  34.     JP    .int
  35.  
  36.     .org    0x58        ; SIO
  37. .int_SIO:
  38.     PUSH    HL
  39.     LD    HL,#.int_0x58
  40.     JP    .int
  41.  
  42.     .org    0x60        ; JOY
  43. .int_JOY:
  44.     PUSH    HL
  45.     LD    HL,#.int_0x60
  46.     JP    .int
  47.  
  48. .int:
  49.     PUSH    AF
  50.     PUSH    BC
  51.     PUSH    DE
  52. 1$:
  53.     LD    A,(HL+)
  54.     OR    (HL)
  55.     JR    Z,2$
  56.     PUSH    HL
  57.     LD    A,(HL-)
  58.     LD    L,(HL)
  59.     LD    H,A
  60.     CALL    3$
  61.     POP    HL
  62.     INC    HL
  63.     JR    1$
  64. 2$:
  65.     POP    DE
  66.     POP    BC
  67.     POP    AF
  68.     POP    HL
  69.     RETI
  70.  
  71. 3$:
  72.     JP    (HL)
  73.  
  74.     ;; GameBoy Header
  75.  
  76.     ;; DO NOT CHANGE...
  77.     .org    0x100
  78. .header:
  79.     NOP
  80.     JP    0x150
  81.     .byte    0xCE,0xED,0x66,0x66
  82.     .byte    0xCC,0x0D,0x00,0x0B
  83.     .byte    0x03,0x73,0x00,0x83
  84.     .byte    0x00,0x0C,0x00,0x0D
  85.     .byte    0x00,0x08,0x11,0x1F
  86.     .byte    0x88,0x89,0x00,0x0E
  87.     .byte    0xDC,0xCC,0x6E,0xE6
  88.     .byte    0xDD,0xDD,0xD9,0x99
  89.     .byte    0xBB,0xBB,0x67,0x63
  90.     .byte    0x6E,0x0E,0xEC,0xCC
  91.     .byte    0xDD,0xDC,0x99,0x9F
  92.     .byte    0xBB,0xB9,0x33,0x3E
  93.  
  94.     ;; Title of the game
  95.     .org    0x134
  96.     .asciz    "Title"
  97.  
  98.     .org    0x144
  99.     .byte    0,0,0
  100.  
  101.     ;; Cartridge type is ROM only
  102.     .org    0x147
  103.     .byte    0
  104.  
  105.     ;; ROM size is 32kB
  106.     .org    0x148
  107.     .byte    0
  108.  
  109.     ;; RAM size is 0kB
  110.     .org    0x149
  111.     .byte    0
  112.  
  113.     ;; Maker ID
  114.     .org    0x14A
  115.     .byte    0x00,0x00
  116.  
  117.     ;; Version number
  118.     .org    0x14C
  119.     .byte    0x01
  120.  
  121.     ;; Complement check
  122.     .org    0x14D
  123.     .byte    0x00
  124.  
  125.     ;; Checksum
  126.     .org    0x14E
  127.     .byte    0x00,0x00
  128.  
  129.     ;; ****************************************
  130.     .org    0x150
  131. .code_start:
  132.     ;; Beginning of the code
  133.     DI            ; Disable interrupts
  134.     LD    D,A        ; Store CPU type in D
  135.     XOR    A
  136.     ;; Initialize the stack
  137.     LD    SP,#.STACK
  138.     ;; Clear from 0xC000 to 0xDFFF
  139.     LD    HL,#0xDFFF
  140.     LD    C,#0x20
  141.     LD    B,#0x00
  142. 1$:
  143.     LD    (HL-),A
  144.     DEC    B
  145.     JR    NZ,1$
  146.     DEC    C
  147.     JR    NZ,1$
  148.     ;; Clear from 0xFE00 to 0xFEFF
  149.     LD    HL,#0xFEFF
  150.     LD    B,#0x00
  151. 2$:
  152.     LD    (HL-),A
  153.     DEC    B
  154.     JR    NZ,2$
  155.     ;; Clear from 0xFF80 to 0xFFFF
  156.     LD    HL,#0xFFFF
  157.     LD    B,#0x80
  158. 3$:
  159.     LD    (HL-),A
  160.     DEC    B
  161.     JR    NZ,3$
  162. ;     LD    (.mode),A    ; Clearing (.mode) is performed when clearing RAM
  163.     ;; Store CPU type
  164.     LD    A,D
  165.     LD    (__cpu),A
  166.  
  167.     ;; Turn the screen off
  168.     CALL    .display_off
  169.  
  170.     ;; Initialize the display
  171.     XOR    A
  172.     LDH    (.SCY),A
  173.     LDH    (.SCX),A
  174.     LDH    (.STAT),A
  175.     LDH    (.WY),A
  176.     LD    A,#0x07
  177.     LDH    (.WX),A
  178.  
  179.     ;; Copy refresh_OAM routine to HIRAM
  180.     LD    BC,#.refresh_OAM
  181.     LD    HL,#.start_refresh_OAM
  182.     LD    B,#.end_refresh_OAM-.start_refresh_OAM
  183. 4$:
  184.     LD    A,(HL+)
  185.     LDH    (C),A
  186.     INC    C
  187.     DEC    B
  188.     JR    NZ,4$
  189.  
  190.     ;; Install interrupt routines
  191.     LD    BC,#.vbl
  192.     CALL    .add_VBL
  193.     LD    BC,#.serial_IO
  194.     CALL    .add_SIO
  195.  
  196.     ;; Standard color palettes
  197.     LD    A,#0b11100100    ; Grey 3 = 11 (Black)
  198.                 ; Grey 2 = 10 (Dark grey)
  199.                 ; Grey 1 = 01 (Light grey)
  200.                 ; Grey 0 = 00 (Transparent)
  201.     LDH    (.BGP),A
  202.     LDH    (.OBP0),A
  203.     LD    A,#0b00011011
  204.     LDH    (.OBP1),A
  205.  
  206.     ;; Turn the screen on
  207.     LD    A,#0b11000000    ; LCD        = On
  208.                 ; WindowBank    = 0x9C00
  209.                 ; Window    = Off
  210.                 ; BG Chr    = 0x8800
  211.                 ; BG Bank    = 0x9800
  212.                 ; OBJ        = 8x8
  213.                 ; OBJ        = Off
  214.                 ; BG        = Off
  215.     LDH    (.LCDC),A
  216.     XOR    A
  217.     LDH    (.IF),A
  218.     LD    A,#0b00001001    ; Pin P10-P13    =   Off
  219.                 ; Serial I/O    =   On
  220.                 ; Timer Ovfl    =   Off
  221.                 ; LCDC        =   Off
  222.                 ; V-Blank    =   On
  223.     LDH    (.IE),A
  224.  
  225.     XOR    A
  226.     LDH    (.NR52),A    ; Turn sound off
  227.     LDH    (.SC),A        ; Use external clock
  228.     LD    A,#.DT_IDLE
  229.     LDH    (.SB),A        ; Send IDLE byte
  230.     LD    A,#0x80
  231.     LDH    (.SC),A        ; Use external clock
  232.  
  233.     CALL    .init
  234.  
  235.     EI            ; Enable interrupts
  236.  
  237.     ;; Call the main function
  238.     CALL    _main
  239.  
  240. 99$:
  241.     JR    99$        ; Wait forever
  242.  
  243.     .org    .MODE_TABLE
  244.     ;; Jump table for modes
  245.     RET
  246.  
  247.     ;; ****************************************
  248.  
  249.     ;; Ordering of segments for the linker
  250.     .area    _CODE
  251.     .area    _DATA
  252.     .area    _LIT
  253.     .area    _BSS
  254.     .area    _HEAP        ; HEAP is for malloc
  255.  
  256.     .area    _BSS
  257.  
  258. __cpu::
  259.     .ds    0x01        ; GB type (GB, PGB, CGB)
  260. .mode::
  261.     .ds    0x01        ; Current mode
  262. __io_out::
  263.     .ds    0x01        ; Byte to send
  264. __io_in::
  265.     .ds    0x01        ; Received byte
  266. __io_status::
  267.     .ds    0x01        ; Status of serial IO
  268. .vbl_done::
  269.     .ds    0x01        ; Is VBL interrupt finished?
  270.  
  271. .int_0x40::
  272.     .blkw    0x08
  273. .int_0x48::
  274.     .blkw    0x08
  275. .int_0x50::
  276.     .blkw    0x08
  277. .int_0x58::
  278.     .blkw    0x08
  279. .int_0x60::
  280.     .blkw    0x08
  281.  
  282.     ;; Runtime library
  283.     .area    _CODE
  284.  
  285.     ;; Call the initialization function for the mode specified in HL
  286. .set_mode::
  287.     LD    A,L
  288.     LD    (.mode),A
  289.  
  290.     LD    BC,#.MODE_TABLE
  291.     SLA    L        ; Multiply mode by 4
  292.     SLA    L
  293.     ADD    HL,BC
  294.     JP    (HL)        ; Jump to initialization routine
  295.  
  296.     ;; Add interrupt routine in BC to the interrupt list
  297. .add_VBL::
  298.     LD    HL,#.int_0x40
  299.     JP    .add_int
  300. .add_LCD::
  301.     LD    HL,#.int_0x48
  302.     JP    .add_int
  303. .add_TIM::
  304.     LD    HL,#.int_0x50
  305.     JP    .add_int
  306. .add_SIO::
  307.     LD    HL,#.int_0x58
  308.     JP    .add_int
  309. .add_JOY::
  310.     LD    HL,#.int_0x60
  311.     JP    .add_int
  312.  
  313.     ;; Remove interrupt BC from interrupt list HL if it exists
  314.     ;; Abort if a 0000 is found (end of list)
  315.     ;; Will only remove last int on list
  316. .remove_int::
  317. 1$:
  318.     LD    A,(HL+)
  319.     LD    E,A
  320.     LD    D,(HL)
  321.     OR    D
  322.     RET    Z        ; No interrupt found
  323.  
  324.     LD    A,E
  325.     CP    C
  326.     JR    NZ,1$
  327.     LD    A,D
  328.     CP    B
  329.     JR    NZ,1$
  330.  
  331.     XOR    A
  332.     LD    (HL-),A
  333.     LD    (HL),A
  334.     INC    A        ; Clear Z flag
  335.     RET
  336.     
  337.     ;; Add interrupt routine in BC to the interrupt list in HL
  338. .add_int:
  339. 1$:
  340.     LD    A,(HL+)
  341.     OR    (HL)
  342.     JR    Z,2$
  343.     INC    HL
  344.     JR    1$
  345. 2$:
  346.     LD    (HL),B
  347.     DEC    HL
  348.     LD    (HL),C
  349.     RET
  350.  
  351.     ;; VBlank interrupt
  352. .vbl:
  353.     CALL    .refresh_OAM
  354.  
  355.     .if    0
  356.     ;; Verify that only one VBlank interrupt occured
  357.     LD    A,(.vbl_done)
  358.     OR    A
  359.     JR    Z,1$
  360.     LDH    A,(.BGP)
  361.     CPL
  362.     LDH    (.BGP),A
  363. 1$:
  364.     .endif
  365.  
  366.     LD    A,#0x01
  367.     LD    (.vbl_done),A
  368.     RET
  369.  
  370.     ;; Wait for VBL interrupt to be finished
  371. .wait_vbl_done::
  372. _wait_vbl_done::
  373.     ;; Check if the screen is on
  374.     LDH    A,(.LCDC)
  375.     ADD    A
  376.     RET    NC        ; Return if screen is off
  377. 1$:
  378.     HALT            ; Wait for any interrupt
  379.     NOP            ; HALT sometimes skips the next instruction
  380.     LD    A,(.vbl_done)    ; Was it a VBlank interrupt?
  381.     ;; Warning: we may lose a VBlank interrupt, if it occurs now
  382.     OR    A
  383.     JR    Z,1$        ; No: back to sleep!
  384.  
  385.     XOR    A
  386.     LD    (.vbl_done),A
  387.     RET
  388.  
  389. .display_off::
  390. _display_off::
  391.     ;; Check if the screen is on
  392.     LDH    A,(.LCDC)
  393.     ADD    A
  394.     RET    NC        ; Return if screen is off
  395. 1$:                ; We wait for the *NEXT* VBL 
  396.     LDH    A,(.LY)
  397.     CP    #0x92        ; Smaller than or equal to 0x91?
  398.     JR    NC,1$        ; Loop until smaller than or equal to 0x91
  399. 2$:
  400.     LDH    A,(.LY)
  401.     CP    #0x91        ; Bigger than 0x90?
  402.     JR    C,2$        ; Loop until bigger than 0x90
  403.  
  404.     LDH    A,(.LCDC)
  405.     AND    #0b01111111
  406.     LDH    (.LCDC),A    ; Turn off screen
  407.     RET
  408.  
  409.     ;; Copy OAM data to OAM RAM
  410. .start_refresh_OAM:
  411.     LD    A,#>.OAM
  412.     LDH    (.DMA),A    ; Put A into DMA registers
  413.     LD    A,#0x28        ; We need to wait 160 ns
  414. 1$:
  415.     DEC    A
  416.     JR    NZ,1$
  417.     RET
  418. .end_refresh_OAM:
  419.  
  420.     ;; Serial interrupt
  421. .serial_IO::
  422.     LD    A,(__io_status) ; Get status
  423.  
  424.     CP    #.IO_RECEIVING
  425.     JR    NZ,10$
  426.  
  427.     ;; Receiving data
  428.     LDH    A,(.SB)        ; Get data byte
  429.     LD    (__io_in),A    ; Store it
  430.     LD    A,#.IO_IDLE
  431.     JR    11$
  432.  
  433. 10$:
  434.  
  435.     CP    #.IO_SENDING
  436.     JR    NZ,99$
  437.  
  438.     ;; Sending data
  439.     LDH    A,(.SB)        ; Get data byte
  440.     CP    #.DT_RECEIVING
  441.     JR    Z,11$
  442.     LD    A,#.IO_ERROR
  443.     JR    12$
  444. 11$:
  445.     LD    A,#.IO_IDLE
  446. 12$:
  447.     LD    (__io_status),A ; Store status
  448.  
  449.     XOR    A
  450.     LDH    (.SC),A        ; Use external clock
  451.     LD    A,#.DT_IDLE
  452.     LDH    (.SB),A        ; Reply with IDLE byte
  453. 99$:
  454.     LD    A,#0x80
  455.     LDH    (.SC),A        ; Enable transfer with external clock
  456.     RET
  457.  
  458. _mode::
  459.     LDA    HL,2(SP)    ; Skip return address
  460.     LD    L,(HL)
  461.     LD    H,#0x00
  462.     CALL    .set_mode
  463.     RET
  464.  
  465. _enable_interrupts::
  466.     EI
  467.     RET
  468.  
  469. _disable_interrupts::
  470.     DI
  471.     RET
  472.  
  473. .reset::
  474. _reset::
  475.     LD    A,(__cpu)
  476.     JP    .code_start
  477.  
  478. _set_interrupts::
  479.     DI
  480.     LDA    HL,2(SP)    ; Skip return address
  481.     XOR    A
  482.     LDH    (.IF),A        ; Clear pending interrupts
  483.     LD    A,(HL)
  484.     LDH    (.IE),A
  485.     EI            ; Enable interrupts
  486.     RET
  487.  
  488. _add_VBL::
  489.     PUSH    BC
  490.     LDA    HL,4(SP)    ; Skip return address and registers
  491.     LD    C,(HL)
  492.     INC    HL
  493.     LD    B,(HL)
  494.     CALL    .add_VBL
  495.     POP    BC
  496.     RET
  497.  
  498. _add_LCD::
  499.     PUSH    BC
  500.     LDA    HL,4(SP)    ; Skip return address and registers
  501.     LD    C,(HL)
  502.     INC    HL
  503.     LD    B,(HL)
  504.     CALL    .add_LCD
  505.     POP    BC
  506.     RET
  507.  
  508. _add_TIM::
  509.     PUSH    BC
  510.     LDA    HL,4(SP)    ; Skip return address and registers
  511.     LD    C,(HL)
  512.     INC    HL
  513.     LD    B,(HL)
  514.     CALL    .add_TIM
  515.     POP    BC
  516.     RET
  517.  
  518. _add_SIO::
  519.     PUSH    BC
  520.     LDA    HL,4(SP)    ; Skip return address and registers
  521.     LD    C,(HL)
  522.     INC    HL
  523.     LD    B,(HL)
  524.     CALL    .add_SIO
  525.     POP    BC
  526.     RET
  527.  
  528. _add_JOY::
  529.     PUSH    BC
  530.     LDA    HL,4(SP)    ; Skip return address and registers
  531.     LD    C,(HL)
  532.     INC    HL
  533.     LD    B,(HL)
  534.     CALL    .add_JOY
  535.     POP    BC
  536.     RET
  537.  
  538.     .area    _HEAP
  539. _malloc_heap_start::
  540.